package tms.view;

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Date;

import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import org.jbundle.util.jcalendarbutton.JCalendarButton;
import tms.Helper;
import tms.controler.SearchController;
import tms.model.Destination;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.FormSpecs;
import com.jgoodies.forms.layout.RowSpec;

@SuppressWarnings("rawtypes")
public class SearchView extends JPanel {

    private static final long serialVersionUID = 1L;

    private JComboBox cmbLeavingFrom;
    private JComboBox cmbGoingTo;

    private JComboBox cmbAdults;
    private JComboBox cmbChildren;
    private JComboBox cmbInfants;
    private JButton btnFindFlights;

    private JRadioButton rdbRoundTrip;
    private JRadioButton rdbOneWay;

    private final SearchController controller;
    private JTextField txtLeavingDate;
    private JTextField txtReturnDate;
    private JCalendarButton clbLeaveDate;
    private JCalendarButton clbReturnDate;
    private JComboBox cmbClass;

    /**
     * Create the panel.
     */
    @SuppressWarnings("unchecked")
    public SearchView(final SearchController controller) {

        Listener listener = new Listener();
        this.controller = controller;

        // get current Date from system
        String nowString = Helper.getNowString(Tools.DATE_FORMAT_NO_TIME);
        Date nowDate = new Date();

        JLabel lblSearchFlight =
                Tools.createLabel("Search flight", Tools.TAHOMA_BOLD_16);

        ButtonGroup bgFlightType = new ButtonGroup();
        rdbRoundTrip = Tools.createRadioButton("Round trip");
        bgFlightType.add(rdbRoundTrip);
        rdbRoundTrip.addActionListener(listener);

        rdbOneWay = Tools.createRadioButton("One way");
        rdbOneWay.setSelected(true);
        bgFlightType.add(rdbOneWay);
        rdbOneWay.addActionListener(listener);

        JLabel lblFrom = Tools.createLabel("Leaving from:");

        JLabel lblGoingTo = Tools.createLabel("Going to:");

        cmbLeavingFrom = Tools.createComboBox();

        cmbGoingTo = Tools.createComboBox();

        JLabel lblDepartureDate = Tools.createLabel("Leave date:");

        JLabel lblReturnDate = Tools.createLabel("Return date:");

        JSeparator separator = new JSeparator();

        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));

        JLabel lblAdults = Tools.createLabel("Adults");
        lblAdults.setBorder(new EmptyBorder(0, 0, 0, 10));
        panel.add(lblAdults);

        cmbAdults = Tools.createComboBox();
        cmbAdults.setEnabled(false);
        panel.add(cmbAdults);

        JLabel lblChildren = Tools.createLabel("Children");
        lblChildren.setBorder(new EmptyBorder(0, 10, 0, 10));
        panel.add(lblChildren);

        cmbChildren = Tools.createComboBox();
        cmbChildren.setEnabled(false);
        panel.add(cmbChildren);

        JLabel lblInfants = Tools.createLabel("Infants");
        lblInfants.setBorder(new EmptyBorder(0, 10, 0, 10));
        panel.add(lblInfants);

        cmbInfants = Tools.createComboBox();
        cmbInfants.setEnabled(false);
        panel.add(cmbInfants);
        setLayout(new FormLayout(new ColumnSpec[] {
                ColumnSpec.decode("7dlu:grow"),
                ColumnSpec.decode("90px:grow"),
                ColumnSpec.decode("90px"),
                ColumnSpec.decode("70px:grow"),
                ColumnSpec.decode("43px:grow"),
                ColumnSpec.decode("90px:grow"),
                ColumnSpec.decode("90px"),
                FormSpecs.RELATED_GAP_COLSPEC,
                ColumnSpec.decode("30px"),
                ColumnSpec.decode("7dlu:grow")},
            new RowSpec[] {
                RowSpec.decode("15dlu"),
                RowSpec.decode("26px"),
                FormSpecs.RELATED_GAP_ROWSPEC,
                RowSpec.decode("2px"),
                FormSpecs.PARAGRAPH_GAP_ROWSPEC,
                RowSpec.decode("23px"),
                FormSpecs.RELATED_GAP_ROWSPEC,
                RowSpec.decode("15px"),
                FormSpecs.LINE_GAP_ROWSPEC,
                RowSpec.decode("25px"),
                FormSpecs.UNRELATED_GAP_ROWSPEC,
                RowSpec.decode("15px"),
                FormSpecs.RELATED_GAP_ROWSPEC,
                RowSpec.decode("25px"),
                RowSpec.decode("25px"),
                RowSpec.decode("2px"),
                FormSpecs.PARAGRAPH_GAP_ROWSPEC,
                RowSpec.decode("25px"),
                FormSpecs.PARAGRAPH_GAP_ROWSPEC,
                RowSpec.decode("25px"),
                FormSpecs.PARAGRAPH_GAP_ROWSPEC,
                RowSpec.decode("25px")}));
        add(rdbRoundTrip, "2, 6, left, top");
        add(rdbOneWay, "3, 6, left, top");
        add(lblFrom, "2, 8, left, top");
        add(cmbLeavingFrom, "2, 10, 3, 1, fill, fill");

        txtLeavingDate = new JTextField();
        txtLeavingDate.setFocusable(false);
        txtLeavingDate.setText(nowString);
        add(txtLeavingDate, "6, 10, 2, 1, fill, fill");
        txtLeavingDate.setColumns(10);

        clbLeaveDate = new JCalendarButton();
        assert (nowDate != null);
        clbLeaveDate.setTargetDate(nowDate);
        clbLeaveDate.addPropertyChangeListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
                if (evt.getNewValue() instanceof Date) {
                    setLeaveDate((Date) evt.getNewValue());
                }
            }
        });
        add(clbLeaveDate, "9, 10, default, fill");
        assert (nowDate != null);
        add(lblGoingTo, "2, 12, left, top");
        add(cmbGoingTo, "2, 14, 3, 1, fill, fill");
        add(lblReturnDate, "6, 12, fill, top");
        add(lblDepartureDate, "6, 8, left, top");
        add(separator, "2, 4, 8, 1, fill, top");
        add(lblSearchFlight, "2, 2, 3, 1, left, top");

        txtReturnDate = new JTextField();
        txtReturnDate.setFocusable(false);
        txtReturnDate.setEnabled(false);
        txtReturnDate.setText(nowString);
        txtReturnDate.setColumns(10);
        add(txtReturnDate, "6, 14, 2, 1, fill, fill");

        clbReturnDate = new JCalendarButton();
        clbReturnDate.setEnabled(false);
        clbReturnDate.setTargetDate(nowDate);
        clbReturnDate.addPropertyChangeListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
                if (evt.getNewValue() instanceof Date) {
                    setReturnDate((Date) evt.getNewValue());
                }
            }
        });
        add(clbReturnDate, "9, 14, default, fill");
        add(new JSeparator(), "2, 16, 8, 1, fill, top");
        add(panel, "2, 20, 8, 1, fill, fill");

        JLabel lblClass = new JLabel("Select class:");
        lblClass.setFont(new Font("Tahoma", Font.PLAIN, 12));
        lblClass.setBorder(new EmptyBorder(0, 0, 0, 10));
        add(lblClass, "2, 18");

        cmbClass = new JComboBox();
        cmbClass.setModel(new DefaultComboBoxModel(SearchController.TICKET_CLASS));
        add(cmbClass, "3, 18, 2, 1, fill, fill");

        btnFindFlights = Tools.createButton("Find flights");
        btnFindFlights.addActionListener(listener);
        add(btnFindFlights, "7, 22, 3, 1, right, fill");

    }

    /**
     * Add a destination to GoingTo ComboBox.
     * @param item
     */
    @SuppressWarnings("unchecked")
    public void addGoingToItem(Destination item) {
        assert (item != null);
        cmbGoingTo.addItem(item);
    }

    /**
     * Add a destination to LeavingFrom ComboBox.
     * @param item
     */
    @SuppressWarnings("unchecked")
    public void addLeavingFromItem(Destination item) {
        assert (item != null);
        cmbLeavingFrom.addItem(item);
    }

    public Destination getLeavingFromFlight() {
        return (Destination) cmbLeavingFrom.getSelectedItem();
    }

    public Destination getGoingToFlight() {
        return (Destination) cmbGoingTo.getSelectedItem();
    }

    public void setLeaveDate(Date date) {
        String dateString;
        if (date == null) {
            return;
        }
        dateString = Helper.dateToString(date, Tools.DATE_FORMAT_NO_TIME);
        txtLeavingDate.setText(dateString);
        clbLeaveDate.setTargetDate(date);
    }

    public String getLeaveString() {
        return txtLeavingDate.getText();
    }

    public Date getLeaveDate() {
        return clbLeaveDate.getTargetDate();
    }

    public void setReturnDate(Date date) {
        String dateString;
        if (date == null) {
            return;
        }
        dateString = Helper.dateToString(date, Tools.DATE_FORMAT_NO_TIME);
        txtReturnDate.setText(dateString);
        clbReturnDate.setTargetDate(date);
    }

    public String getReturnString() {
        return txtReturnDate.getText();
    }

    public Date getReturnDate() {
        return clbReturnDate.getTargetDate();
    }

    public String getTicketClass() {
        return (String) cmbClass.getSelectedItem();
    }

    public boolean isRoundTripSelected() {
        return rdbRoundTrip.isSelected();
    }

    /*
     *  a common listener for all components in SearchFlightPanel
     */
    class Listener implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            Object source = e.getSource();
            if (source == btnFindFlights) {
                if (controller.validateData()) {
                    controller.searchFlights(
                            isRoundTripSelected(),
                            getLeavingFromFlight().getId(),
                            getLeaveDate(),
                            getGoingToFlight().getId(),
                            getReturnDate(),
                            getTicketClass()
                    );
                }
            } else if (source == rdbRoundTrip) {
                // enable controls related to RoundTrip
                clbReturnDate.setEnabled(true);
                txtReturnDate.setEnabled(true);
            } else if (source == rdbOneWay) {
                // disable controls related to RoundTrip
                clbReturnDate.setEnabled(false);
                txtReturnDate.setEnabled(false);
            }
        }
    }
}
